package com.cp.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cp.base.util.JwtUtils;
import com.cp.common.exception.Assert;
import com.cp.common.result.ResponseEnum;
import com.cp.common.util.MD5;
import com.cp.core.mapper.UserInfoMapper;
import com.cp.core.pojo.entity.UserAccount;
import com.cp.core.pojo.entity.UserInfo;
import com.cp.core.pojo.entity.UserLoginRecord;
import com.cp.core.pojo.query.UserInfoQuery;
import com.cp.core.pojo.vo.LoginVo;
import com.cp.core.pojo.vo.RegisterVo;
import com.cp.core.pojo.vo.UserInfoVo;
import com.cp.core.service.UserAccountService;
import com.cp.core.service.UserInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cp.core.service.UserLoginRecordService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * <p>
 * 用户基本信息 服务实现类
 * </p>
 *
 * @author ming
 * @since 2022-07-27
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    @Resource
    private RedisTemplate redisTemplate;
    @Value("${userInfo.avatar}")
    private String defaultAvatar;
    @Resource
    private UserAccountService userAccountService;
    @Resource
    private UserLoginRecordService userLoginRecordService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(RegisterVo registerVo) {
        //校验用户注册信息
        this.assertUserInfo(registerVo);

        //判断用户是否被注册
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("mobile", registerVo.getMobile());
        Integer count = baseMapper.selectCount(wrapper);
        Assert.isTrue(count==0,ResponseEnum.MOBILE_EXIST_ERROR);

        //插入用户记录信息 user_info
        UserInfo userInfoEntity = new UserInfo();
        BeanUtils.copyProperties(registerVo,userInfoEntity);
        userInfoEntity.setPassword(MD5.encrypt(userInfoEntity.getPassword()));
        //设置状态
        userInfoEntity.setStatus(RegisterVo.STATUS_NORMAL);
        userInfoEntity.setHeadImg(defaultAvatar);
        baseMapper.insert(userInfoEntity);
        //插入用户账户记录 user_account
        UserAccount userAccount = new UserAccount();
        userAccount.setUserId(userInfoEntity.getId());
        userAccountService.save(userAccount);
    }

    @Override
    @Transactional
    public UserInfoVo login(LoginVo loginVo, HttpServletRequest request) {
        Assert.notEmpty(loginVo.getMobile(), ResponseEnum.MOBILE_NULL_ERROR);
        String password = loginVo.getPassword();
        Assert.notEmpty(password,ResponseEnum.PASSWORD_NULL_ERROR);
        password = MD5.encrypt(password);
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("mobile",loginVo.getMobile()).eq("password",password).eq("user_type",loginVo.getUserType());
        UserInfo userInfo = this.baseMapper.selectOne(wrapper);
        Assert.notNull(userInfo,ResponseEnum.LOGIN_USER_OR_PASSWORD_ERROR);
        Assert.isTrue(userInfo.getStatus()==1,ResponseEnum.LOGIN_LOKED_ERROR);
        //记录登录日志
        String ip = request.getRemoteHost();
        UserLoginRecord userLoginRecord = new UserLoginRecord();
        userLoginRecord.setUserId(userInfo.getId());

        userLoginRecord.setIp(ip);
        userLoginRecordService.save(userLoginRecord);
        //生成token
        String token = JwtUtils.createToken(userInfo.getId(), userInfo.getName());
        //组装userInfoVo对象
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(userInfo,userInfoVo);
        userInfoVo.setToken(token);
        return userInfoVo;

    }

    @Override
    public IPage<UserInfo> listPage(Page<UserInfo> pageEntity, UserInfoQuery userInfoQuery) {
       if(userInfoQuery==null){
           return baseMapper.selectPage(pageEntity,null);
       }
       QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        String mobile = userInfoQuery.getMobile();
        Integer status = userInfoQuery.getStatus();
        Integer userType = userInfoQuery.getUserType();
        wrapper .eq(StringUtils.isNotBlank(mobile),"mobile",mobile)
                .eq(status!=null,"status",status)
                .eq(userType!=null,"user_type",userType);

        return this.baseMapper.selectPage(pageEntity,wrapper);

    }

    @Override
    public void lockOrUnLock(Long id, Integer status) {
        status = status==0?1:0;
        UserInfo userInfo = new UserInfo();
        userInfo.setStatus(status);
        userInfo.setId(id);
        this.baseMapper.updateById(userInfo);
    }

    @Override
    public boolean checkMobile(String mobile) {
        return this.baseMapper.selectCount(new QueryWrapper<UserInfo>().eq("mobile",mobile))>0 ;
    }

    private void assertUserInfo(RegisterVo registerVo){

        String mobile = registerVo.getMobile();
        Assert.notEmpty(mobile, ResponseEnum.MOBILE_NULL_ERROR);
        Assert.notEmpty(registerVo.getPassword(),ResponseEnum.PASSWORD_NULL_ERROR);
        String code = (String) redisTemplate.opsForValue().get("srb:sms:code:"+mobile);
        Assert.notEmpty(code,ResponseEnum.CODE_NULL_ERROR);
        Assert.notEmpty(registerVo.getCode(),ResponseEnum.CODE_NULL_ERROR);
        Assert.equals(code, registerVo.getCode(),ResponseEnum.CODE_ERROR);
    }
}
